package com.jhw.ymcc.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.jhw.ymcc.domain.KillActivity;
import com.jhw.ymcc.domain.KillCourse;
import com.jhw.ymcc.exception.GlobalCustomException;
import com.jhw.ymcc.exception.GlobalErrorCode;
import com.jhw.ymcc.mapper.KillActivityMapper;
import com.jhw.ymcc.service.IKillActivityService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.jhw.ymcc.service.IKillCourseService;
import com.jhw.ymcc.util.AssertUtil;
import org.redisson.api.RSemaphore;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author jhw
 * @since 2022-10-20
 */
@Service
public class KillActivityServiceImpl extends ServiceImpl<KillActivityMapper, KillActivity> implements IKillActivityService {

    @Autowired
    private IKillCourseService killCourseServicel;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Override
    public void publish(Long killActivityId) {
        // 判断当前活动不能为空
        KillActivity killActivity = selectById(killActivityId);
        AssertUtil.isNotNull(killActivity, GlobalErrorCode.ERROR);
        // 判断当前状态必须是待发布
        boolean wait = killActivity.getPublishStatus() == KillActivity.STATUS_WAIT_PUBLISH;
        AssertUtil.isTrue(wait, GlobalErrorCode.ERROR);
        // 发布活动必须在活动开始之前
        Date now = new Date();
        boolean after = killActivity.getBeginTime().after(now);
        AssertUtil.isTrue(after, GlobalErrorCode.ERROR);
        // 根据活动id查到所有的秒杀课程，判断是否存在
        List<KillCourse> killCourses = selectKillCourseBykillActivityId(killActivityId);
        if (killCourses == null || killCourses.size() < 0){
            throw new GlobalCustomException(GlobalErrorCode.ERROR);
        }
        //
        killCourses.forEach(killCourse -> {
            // 设置信号量
            RSemaphore semaphore = redissonClient.getSemaphore(killActivityId + ":" + killCourse.getId());
            boolean isSetPermits  = semaphore.trySetPermits(killCourse.getKillCount());
            if (isSetPermits ){
                // 这里两个key都需要设置成string
                redisTemplate.opsForHash().put(
                        "actity" + killActivityId,
                        killCourse.getId().toString(),
                        killCourse
                );
                // 修改发布课程发布状态以及时间
                killCourse.setPublishStatus(KillCourse.ON_PUBLISH);
                killCourse.setPublishTime(now);
                killCourseServicel.updateById(killCourse);
            }
        });
        // 修改活动发布状态以及时间
        killActivity.setPublishStatus(KillCourse.ON_PUBLISH);
        killActivity.setPublishTime(now);
        updateById(killActivity);

    }

    private List<KillCourse> selectKillCourseBykillActivityId(Long killActivityId) {
        Wrapper<KillCourse> wrapper = new EntityWrapper<>();
        wrapper.eq("activity_id", killActivityId);
        return killCourseServicel.selectList(wrapper);
    }
}
